#include "stdafx.h"
#include "models/dwm_op.h"
#include "models/atom_interface/ai_config.h"
#include "poke_const.h"
#include "molecular_core.h"
#include <dwmapi.h>
#pragma comment(lib, "dwmapi.lib")

DwmOp::DwmOp()
{
    ResetInfo();
}

DwmOp::~DwmOp()
{

}

bool
DwmOp::OnEvent(const M::AtomEndPoint &oSrcAtom, int nEventId, void *pParams)
{
    switch(nEventId) {
    case PEI_UPDATE_MODEL:
        return RetrieveInfo();
    }

    return true;
}

bool
DwmOp::OnExecute(const M::AtomEndPoint &oSrcAtom, int nFuncId, void *pParams, void *pIOParams)
{
    bool bRet = false;
    switch(nFuncId) {
    case PFI_GET_SYSTEM_DWM_ATTRIBUTES:
        bRet = OnGetSystemDwmInfo((SystemDwmInfo *)pParams);
        break;
    case PFI_GET_WINDOW_DWM_ATTRIBUTES:
        bRet = OnGetWindowDwmAttrList((WindowDwmAttrList *)pParams);
        break;
    case PFI_SET_WINDOW_DWM_ATTRIBUTES:
        bRet = OnSetWindowDwmAttrList((WindowDwmAttrList *)pParams);
        break;
    case PFI_EXTEND_FRAME_INTO_CHILD_AREA:
        bRet = OnExtendFrameIntoChildArea((MARGINS *)pParams);
        break;
    }

    if(NULL != pIOParams) {
        (*(bool *)pIOParams) = bRet;
    }

    return bRet;
}

bool
DwmOp::RetrieveInfo()
{
    ResetInfo();

    return true;
}

void
DwmOp::ResetInfo()
{
}

bool
DwmOp::OnGetSystemDwmInfo(SystemDwmInfo *pKey)
{
    if(NULL == pKey) {
        return false;
    }

    BOOL bEnabled = FALSE;
    DwmIsCompositionEnabled(&bEnabled);
    pKey->bIsDwmCompositionEnabled = !!bEnabled;

    return true;
}

bool
DwmOp::OnGetWindowDwmAttrList(WindowDwmAttrList *pKey)
{
    if(NULL == pKey) {
        return false;
    }

    PokeConfig oConfig = {0};
    Execute(PAN_CONFIG, PFI_GET_CONFIG, &oConfig, NULL);
    if(NULL == oConfig.hWindow || !IsWindow(oConfig.hWindow)) {
        return false;
    }

    WindowDwmAttrList::iterator oAttrIt = pKey->begin();
    while(oAttrIt != pKey->end()) {
        DwmGetWindowAttribute(oConfig.hWindow, oAttrIt->first, oAttrIt->second.pValue, oAttrIt->second.nValueSize);
        ++oAttrIt;
    }

    return true;
}

bool
DwmOp::OnSetWindowDwmAttrList(WindowDwmAttrList *pKey)
{
    if(NULL == pKey) {
        return false;
    }

    PokeConfig oConfig = {0};
    Execute(PAN_CONFIG, PFI_GET_CONFIG, &oConfig, NULL);
    if(NULL == oConfig.hWindow || !IsWindow(oConfig.hWindow)) {
        return false;
    }

    WindowDwmAttrList::iterator oAttrIt = pKey->begin();
    while(oAttrIt != pKey->end()) {
        DwmSetWindowAttribute(oConfig.hWindow, oAttrIt->first, oAttrIt->second.pValue, oAttrIt->second.nValueSize);
        ++oAttrIt;
    }

    return true;
}

bool
DwmOp::OnExtendFrameIntoChildArea(MARGINS *pMargins)
{
    if(NULL == pMargins) {
        return false;
    }

    PokeConfig oConfig = {0};
    Execute(PAN_CONFIG, PFI_GET_CONFIG, &oConfig, NULL);
    if(NULL == oConfig.hWindow || !IsWindow(oConfig.hWindow)) {
        return false;
    }

    ::DwmExtendFrameIntoClientArea(oConfig.hWindow, pMargins);

    return true;
}